using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Styx.Plugins;
using System.Threading;
using System.Globalization;
using Styx.Common;
using System.Diagnostics;
using Styx.WoWInternals.WoWObjects;
using Styx;
using System.IO;
using System.Windows.Forms;
using System.Windows.Media;
using Styx.CommonBot;
using Styx.Common.Helpers;
using Styx.WoWInternals;
using AIMLbot;

namespace ShutUp_AIML
{
    public class ShutUp_AIML : HBPlugin
    {
        #region Nothing to see here!

        public override string Author { get { return "BarryDurex"; } }
        public override Version Version { get { return new Version(2, 0, 129); } }
        public override string Name { get { return "[ShutUp - AIML]"; } }
        public override string ButtonText { get { return "[ShutUp - " +  "]"; } }
        public override bool WantButton { get { return true; } }

        private bool initialized = false;
        public static Stopwatch loopTimer = new Stopwatch();
        public static readonly WaitTimer _updateList = new WaitTimer(TimeSpan.FromMinutes(10));
        private static LocalPlayer Me { get { return StyxWoW.Me; } }
        public static string ShutUpLogLocation = Application.StartupPath + "\\Plugins\\ShutUpAIML\\Logs\\ShutUp_" + Me.Name + ".txt";
        public string Forumlink = "http://www.thebuddyforum.com/honorbuddy-forum/plugins/monitoring/94401-shutup-aiml-v2-your-ultimate-chat-manager-multilingual.html";
        private Thread newThread;
        public static bool inipulse = false;

        #region AIMLBot
        private readonly Random _rand = new Random(DateTime.Now.Millisecond);
        private Bot myBot;
        private User myUser;
        private bool _working = false;
        public static Queue<ChatMessage> answerQueue = new Queue<ChatMessage>();
        private static List<string> DefaultMesg = new List<string>();
        #endregion

        public static void dlog(string message, params object[] args)
        { Logging.WriteDiagnostic(Colors.Firebrick,"[ShutUp - AIML]: " + message, args); }

        public static void dlog(LogLevel logLvl, string message, params object[] args)
        { /*slog(Colors.Red, "error - look in the HB-Log");*/ Logging.Write(logLvl, Colors.Firebrick, DateTime.Now.ToLongTimeString() + " - [ShutUp - AIML]: " + message, args); }

        public static void slog(Color color, string message, params object[] args)
        { Logging.Write(color, "[ShutUp - AIML]: " + message, args); }

        public static void slog(string message, params object[] args)
        { Logging.Write(Colors.Orchid, "[ShutUp - AIML]: " + message, args); }

        #endregion

        #region on button press
        public override void OnButtonPress()
        {
            var _configForm = new SettingsForm();
            _configForm.ShowDialog();
        }
        #endregion

        public ShutUp_AIML()
        {
            Chat.Whisper += ChatHelper.newChat_Whisper;
            Lua.Events.AttachEvent("CHAT_MSG_BN_WHISPER", ChatHelper.newChat_BNWhisper);
            Chat.Party += ChatHelper.newChat_Party;
            Chat.PartyLeader += ChatHelper.newChat_Party;
            Chat.Guild += ChatHelper.newChat_Guild;
            Chat.Say += ChatHelper.newChat_Say;
            Chat.Yell += ChatHelper.newChat_Yell;
            Chat.Raid += ChatHelper.newChat_Raid;
            Chat.RaidLeader += ChatHelper.newChat_Raid;
            Chat.Officer += ChatHelper.newChat_Officer;
            Chat.RaidWarning += ChatHelper.newChat_Raid;
            Chat.Battleground += ChatHelper.newChat_Battleground;
        }
        
        public override void OnEnable()
        {
            if (initialized)
                return;
            initialized = true;

            NotifyIconHelper.Initialize();

            //FriendsList._update();
            _updateList.Reset();

            
            BotEvents.OnBotStopped += stopBot;
            BotEvents.OnBotStarted += startBot;


            myBot = new Bot();
            myUser = new User("bot", myBot);

            dlog("- Initialized - {0} - v{1} - [{2}]", Name, Version.ToString(), Lua.GetReturnVal<string>("return GetLocale()", 0));
        }

        public static void DefMsg()
        {
            DefaultMesg.Clear();
            if (ShutUpGlobalSettings.Instance.randomAnswer != null)
                foreach (string msg in ShutUpGlobalSettings.Instance.randomAnswer)
                    DefaultMesg.Add(msg);
        }

        private void startBot(EventArgs args)
        {
            dlog("- startBot");
            answerQueue = new Queue<ChatMessage>();
            _working = false;
            slogSettings();
            loopTimer.Stop();

            //Chat.Whisper += ChatHelper.newChat_Whisper;
            //Lua.Events.AttachEvent("CHAT_MSG_BN_WHISPER", ChatHelper.newChat_BNWhisper);
            //Chat.Party += ChatHelper.newChat_Party;
            //Chat.PartyLeader += ChatHelper.newChat_Party;
            //Chat.Guild += ChatHelper.newChat_Guild;
            //Chat.Say += ChatHelper.newChat_Say;
            //Chat.Yell += ChatHelper.newChat_Yell;
            //Chat.Battleground += ChatHelper.newChat_Battleground;
            //Chat.Raid += ChatHelper.newChat_Raid;
            //Chat.RaidLeader += ChatHelper.newChat_Raid;
            //Chat.Officer += ChatHelper.newChat_Officer;
            //Chat.RaidWarning += ChatHelper.newChat_Raid;


            if (ShutUpSettings.Instance.useNotifyIcon && !NotifyIconHelper.NotifyIcn.Visible && Styx.Plugins.PluginManager.Plugins.FirstOrDefault(p => p.Name == "[ShutUp - AIML]").Enabled)
            { NotifyIconHelper.NotifyIcn.Visible = true; NotifyIconHelper.NotifyIcn.ShowBalloonTip(3500, "[ShutUp] - (" + StyxWoW.Me.Name + ")", "You will find [ShutUp] here.", ToolTipIcon.Info); }
            
            #region File.Create(ShutUpLogLocation)
            if (!File.Exists(ShutUpLogLocation))
            {
                try
                {
                    File.Create(ShutUpLogLocation);
                    Thread.Sleep(300);
                }
                catch (Exception ex)
                {
                    dlog(ex.ToString());
                }
            }
            #endregion
        }

        private void stopBot(EventArgs args)
        {
            try
            {
                dlog("- stopBot");
                _working = false;
                inipulse = false;
                //Chat.Whisper -= new Chat.ChatMessageHandlerEx<Chat.ChatWhisperEventArgs>(ChatHelper.newChat_Whisper);
                //Chat.Party -= new Chat.ChatMessageHandlerEx<Chat.ChatLanguageSpecificEventArgs>(ChatHelper.newChat_Party);
                //Chat.PartyLeader -= new Chat.ChatMessageHandlerEx<Chat.ChatLanguageSpecificEventArgs>(ChatHelper.newChat_Party);
                //Chat.Say -= new Chat.ChatMessageHandlerEx<Chat.ChatLanguageSpecificEventArgs>(ChatHelper.newChat_Say);
                //Chat.Guild -= new Chat.ChatMessageHandlerEx<Chat.ChatGuildEventArgs>(ChatHelper.newChat_Guild);
                //Chat.Yell -= new Chat.ChatMessageHandlerEx<Chat.ChatLanguageSpecificEventArgs>(ChatHelper.newChat_Yell);
                //Chat.Battleground -= new Chat.ChatMessageHandlerEx<Chat.ChatLanguageSpecificEventArgs>(ChatHelper.newChat_Battleground);
                //Chat.Raid -= new Chat.ChatMessageHandlerEx<Chat.ChatLanguageSpecificEventArgs>(ChatHelper.newChat_Raid);
                //Chat.RaidLeader -= new Chat.ChatMessageHandlerEx<Chat.ChatLanguageSpecificEventArgs>(ChatHelper.newChat_Raid);
                //Chat.Officer -= new Chat.ChatMessageHandlerEx<Chat.ChatLanguageSpecificEventArgs>(ChatHelper.newChat_Officer);
                //Chat.RaidWarning -= new Chat.ChatMessageHandlerEx<Chat.ChatLanguageSpecificEventArgs>(ChatHelper.newChat_Raid);
                //Lua.Events.DetachEvent("CHAT_MSG_BN_WHISPER", ChatHelper.newChat_BNWhisper);
                NotifyIconHelper.NotifyIcn.Visible = false;
            }
            catch (Exception ex)
            { Logging.WriteException(ex); }
        }

        public override void OnDisable()
        {
            try
            {
                stopBot(null);
                //System.Media.SystemSounds.Asterisk.Play();
                FriendsList.newThread.Abort();
                //if (ChatHelper._timer.Enabled)
                //    ChatHelper._timer.Stop();
                NotifyIconHelper.NotifyIcn.Visible = false;
                NotifyIconHelper.NotifyIcn.Dispose();
                newThread.Abort();
            }
            catch (Exception ex) { Logging.WriteException(ex); }
            finally
            {
                dlog("- Dispose");
            }
        }

        public override void Pulse()
        {
            #region update friedslists
            if ((!Me.Combat && _updateList.IsFinished) || !FriendsList.isFriendListInitialize)
            { _updateList.Reset(); FriendsList.Update(); }
            #endregion

            #region sound loop
            if (loopTimer.IsRunning && loopTimer.ElapsedMilliseconds > (TimeSpan.FromSeconds(ShutUpSettings.Instance.SoundLoopEvery).Milliseconds))
            {
                dlog("sound loop: {0}", ChatHelper.loop);
                loopTimer.Reset(); loopTimer.Start();
                ChatHelper.loop++;
                ChatHelper.PlaySound(ChatHelper.soundLoopStatus);

                if (ChatHelper.loop == ShutUpSettings.Instance.SoundLoop) { ChatHelper.loop = 0; loopTimer.Stop(); }
            }
            #endregion

            #region inipulse

            if (!inipulse)
            {



                inipulse = true;
            }

            #endregion

            if (answerQueue.Count > 0 && !_working) { handleMessage(answerQueue.Dequeue()); }

            if (ShutUpGlobalSettings.Instance.UpdateCheck && (newThread == null || !newThread.IsAlive))
            {
                //TimeSpan ts = (DateTime.Now - ShutUpGlobalSettings.Instance.UpdateCheck_last);
                if ((DateTime.Now - DateTime.FromBinary(ShutUpGlobalSettings.Instance.UpdateCheck_Last)).Hours >= 6)
                {
                    newThread = new Thread(updateCheck) { IsBackground = true };
                    newThread.Start();
                }
            }
        }

        private void updateCheck()
        {
            System.Net.WebClient wClient = new System.Net.WebClient();
            string strSource = wClient.DownloadString("http://shutup.googlecode.com/svn/trunk/version/versionAIML.txt");
            Version _v = new Version(strSource);

            if (Version < _v)
            {
                string _msg = string.Format("a new version is available! \n Version: {0} \nDo you want to visit the forum now? {0}", strSource);

                if (MessageBox.Show(_msg, "new Version", MessageBoxButtons.OKCancel) == DialogResult.OK)
                    System.Diagnostics.Process.Start(Forumlink);
            }

            ShutUpGlobalSettings.Instance.UpdateCheck_Last = DateTime.Now.ToBinary();
        }

        private void handleMessage(ChatMessage e)
        {
            dlog("handleMessage");
            _working = true;
            string returnMessage = string.Empty;
            try
            {
                if (ShutUpSettings.Instance.answerUseAIML)
                {
                    Request r = new Request(e.message, myUser, myBot);
                    Result res = myBot.Chat(r);
                    Thread.Sleep(101);
                    returnMessage = res.Output;
                    if (string.IsNullOrEmpty(returnMessage) && DefaultMesg.Count > 0) returnMessage = DefaultMesg[_rand.Next(0, DefaultMesg.Count())].ToString();
                    if (returnMessage.Contains("dontedit_namespacer")) returnMessage.Replace("dontedit_namespacer", e.Author);
                    if (returnMessage.Contains("Unknown")) returnMessage.Replace("Unknown", "...");
                }

            dlog("handleMessage: {0} - {1} - {2}", returnMessage, e.Status, e.BnetID);
            ChatHelper.answerPlayer(e.Author, returnMessage, e.Status, e.BnetID);

            }
            catch(Exception ex)
            { Logging.WriteException(ex); _working = false; }
            finally { }
            _working = false;
        }

        public static void slogSettings()
        {
            dlog(" ");
            dlog("######################");
            dlog("### ShutUpSettings ###");
            dlog("######################");
            dlog("answerAfterSec = {0}", ShutUpSettings.Instance.answerAfterSec);
            dlog("answerUseAIML = {0}", ShutUpSettings.Instance.answerUseAIML);
            dlog("answerUseRnd = {0}", ShutUpSettings.Instance.answerUseRnd);
            dlog("answerWisper_Friends = {0}", ShutUpSettings.Instance.answerWisper_Friends);
            dlog("answerWisper_unknown = {0}", ShutUpSettings.Instance.answerWisper_unknown);
            dlog("ignoAll = {0}", ShutUpSettings.Instance.ignoAll);
            dlog("ignoNo = {0}", ShutUpSettings.Instance.ignoNo);
            dlog("ignoXW = {0}", ShutUpSettings.Instance.ignoXW);
            dlog("ingameIgno = {0}", ShutUpSettings.Instance.ingameIgno);
            dlog("myName_answer = {0}", ShutUpSettings.Instance.myName_answer);
            dlog("myName_list = {0}", ShutUpSettings.Instance.myName_list);
            dlog("saveLog = {0}", ShutUpSettings.Instance.saveLog);
            dlog("selectedSoundFriends = {0}", ShutUpSettings.Instance.selectedSoundFriends);
            dlog("selectedSoundMyName = {0}", ShutUpSettings.Instance.selectedSoundMyName);
            dlog("selectedSoundUnknown = {0}", ShutUpSettings.Instance.selectedSoundUnknown);
            dlog("softIgnoAfter = {0}", ShutUpSettings.Instance.softIgnoAfter);
            dlog("softIgnoFrAfter = {0}", ShutUpSettings.Instance.softIgnoFrAfter);
            dlog("softIgnoFriend = {0}", ShutUpSettings.Instance.softIgnoFriend);
            dlog("SoundByFriend = {0}", ShutUpSettings.Instance.SoundByFriend);
            dlog("SoundByMyName = {0}", ShutUpSettings.Instance.SoundByMyName);
            dlog("SoundByUnknown = {0}", ShutUpSettings.Instance.SoundByUnknown);
            dlog("SoundLoop = {0}", ShutUpSettings.Instance.SoundLoop);
            dlog("SoundLoopEvery = {0}", ShutUpSettings.Instance.SoundLoopEvery);
            dlog("useExternalPlayer_Friends = {0}", ShutUpSettings.Instance.useExternalPlayer_Friends);
            dlog("useExternalPlayer_myName = {0}", ShutUpSettings.Instance.useExternalPlayer_myName);
            dlog("useExternalPlayer_unknown = {0}", ShutUpSettings.Instance.useExternalPlayer_unknown);
            dlog("UseFriedlist1 = {0}", ShutUpSettings.Instance.UseFriedlist1);
            dlog("UseGuildMaster = {0}", ShutUpSettings.Instance.UseGuildMaster);
            dlog("UseGuildMembersList = {0}", ShutUpSettings.Instance.UseGuildMembersList);
            dlog("UseGuildOffisList = {0}", ShutUpSettings.Instance.UseGuildOffisList);
            dlog("UseInGameFriedlist = {0}", ShutUpSettings.Instance.UseInGameFriedlist);
            dlog("UseBNetFriedlist = {0}", ShutUpSettings.Instance.UseBNetFriedlist);
            dlog("FDF", ShutUpSettings.Instance.UseBNetFriedlist);
            dlog("############################");
            dlog("### ShutUpGlobalSettings ###");
            dlog("############################");
            dlog("FriendList1.Count = {0}", ShutUpGlobalSettings.Instance.FriendList1.ToList().Count);
            dlog("GM_Answer = {0}", ShutUpGlobalSettings.Instance.GM_Answer);
            dlog("(old stuff) GM_AnswerText = {0}", ShutUpGlobalSettings.Instance.GM_AnswerText);
            dlog("GM Messages = {0}", GMAlarmMessage.Instance.Messages.ToList().Count);
            dlog("GM_ExtPlayer count = {0}", ShutUpGlobalSettings.Instance.GM_ExtPlayer);
            dlog("GM_Logout = {0}", ShutUpGlobalSettings.Instance.GM_Logout);
            dlog("GM_PlaySound = {0}", ShutUpGlobalSettings.Instance.GM_PlaySound);
            dlog("GM_SelectedSound = {0}", ShutUpGlobalSettings.Instance.GM_SelectedSound);
            dlog("GM_KillRelog = {0}", ShutUpGlobalSettings.Instance.GM_KillRelog);
            dlog("myName_check_bg = {0}", ShutUpGlobalSettings.Instance.myName_check_bg);
            dlog("myName_check_guild = {0}", ShutUpGlobalSettings.Instance.myName_check_guild);
            dlog("myName_check_party = {0}", ShutUpGlobalSettings.Instance.myName_check_party);
            dlog("myName_check_raid = {0}", ShutUpGlobalSettings.Instance.myName_check_raid);
            dlog("myName_check_say = {0}", ShutUpGlobalSettings.Instance.myName_check_say);
            dlog("myName_check_yell = {0}", ShutUpGlobalSettings.Instance.myName_check_yell);
            dlog("myName_list.Count = {0}", ShutUpGlobalSettings.Instance.myName_list.ToList().Count);
            dlog("myName_showPopUp = {0}", ShutUpGlobalSettings.Instance.myName_showPopUp);
            dlog("randomAnswer.Count = {0}", ShutUpGlobalSettings.Instance.randomAnswer.ToList().Count);
            dlog("soundFiles.Count = {0}", ShutUpGlobalSettings.Instance.soundFiles.ToList().Count);
            dlog("UpdateCheck = {0}", ShutUpGlobalSettings.Instance.UpdateCheck);
            dlog("UpdateCheck_Last = {0}", DateTime.FromBinary(ShutUpGlobalSettings.Instance.UpdateCheck_Last));
            dlog("writeDbug = {0}", ShutUpGlobalSettings.Instance.writeDbug);
            dlog("######################");
            dlog(" ");
        }

    }

        public class ChatMessage
        {
            public string message;
            public string Author;
            public string Status;
            public string BnetID;

            public ChatMessage(string Message, string Author, string Status, string BnetID)
            {
                this.message = Message;
                this.Author = Author;
                this.Status = Status;
                this.BnetID = BnetID;
            }
        }
}
